package com.ruoyi.controller;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.domain.TpLicenseInfo;
import com.ruoyi.dto.LicenseDTO;
import com.ruoyi.platform.annotation.Log;
import com.ruoyi.platform.core.controller.BaseController;
import com.ruoyi.platform.core.domain.AjaxResult;
import com.ruoyi.platform.core.page.TableDataInfo;
import com.ruoyi.platform.enums.BusinessType;
import com.ruoyi.platform.utils.ServletUtils;
import com.ruoyi.platform.utils.StringUtil;
import com.ruoyi.platform.utils.ip.IpUtils;
import com.ruoyi.platform.utils.poi.ExcelUtil;
import com.ruoyi.service.ITpLicenseInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.Base64Utils;
import org.springframework.web.bind.annotation.*;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletResponse;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;

/**
 * LicenseInfoController
 *
 * @author liugang
 * @date 2022-12-05
 */
@RestController
@RequestMapping("/system/LicenseInfo")
@Api(tags = {"LicenseInfo服务"})
public class LicenseInfoController extends BaseController {

    @Autowired
    private ITpLicenseInfoService tpLicenseInfoService;

    private static final String PASSWORD = "megmeet123456789"; // 加密秘钥

    private static final String ENCODING = "UTF-8";


    /**
     * 查询LicenseInfo列表
     */
    @PreAuthorize("@ss.hasPermi('system:LicenseInfo:list')")
    @GetMapping("/list")
    @ApiOperation(value = "查询LicenseInfo列表", httpMethod = "GET", notes = "查询LicenseInfo列表")
    public TableDataInfo list(TpLicenseInfo tpLicenseInfo) {
        startPage();
        List<TpLicenseInfo> list = tpLicenseInfoService.selectTpLicenseInfoList(tpLicenseInfo);
        return getDataTable(list);
    }

    /**
     * 导出LicenseInfo列表
     */
    @PreAuthorize("@ss.hasPermi('system:LicenseInfo:export')")
    @Log(title = "LicenseInfo", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @ApiOperation(value = "导出LicenseInfo列表", httpMethod = "POST", notes = "导出LicenseInfo列表")
    public void export(HttpServletResponse response, TpLicenseInfo tpLicenseInfo) {
        List<TpLicenseInfo> list = tpLicenseInfoService.selectTpLicenseInfoList(tpLicenseInfo);
        ExcelUtil<TpLicenseInfo> util = new ExcelUtil<>(TpLicenseInfo.class);
        util.exportExcel(response, list, "LicenseInfo数据");
    }

    /**
     * 获取LicenseInfo详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:LicenseInfo:query')")
    @GetMapping(value = "/{id}")
    @ApiOperation(value = "获取LicenseInfo详细信息", httpMethod = "GET", notes = "获取LicenseInfo详细信息")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return AjaxResult.success(tpLicenseInfoService.selectTpLicenseInfoById(id));
    }


    /**
     * 修改LicenseInfo
     */
    @PreAuthorize("@ss.hasPermi('system:LicenseInfo:edit')")
    @Log(title = "LicenseInfo", businessType = BusinessType.UPDATE)
    @PutMapping
    @ApiOperation(value = "修改LicenseInfo", httpMethod = "PUT", notes = "修改LicenseInfo")
    public AjaxResult edit(@RequestBody TpLicenseInfo tpLicenseInfo) {
        return toAjax(tpLicenseInfoService.updateTpLicenseInfo(tpLicenseInfo));
    }

    /**
     * 删除LicenseInfo
     */
    @PreAuthorize("@ss.hasPermi('system:LicenseInfo:remove')")
    @Log(title = "LicenseInfo", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    @ApiOperation(value = "删除LicenseInfo", httpMethod = "DELETE", notes = "删除LicenseInfo")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(tpLicenseInfoService.deleteTpLicenseInfoByIds(ids));
    }


    @PostMapping
    @ResponseBody
    public AjaxResult getLicense(@RequestBody LicenseDTO licenseDTO) {
        if (licenseDTO.getUnit() != null) {
            switch (licenseDTO.getUnit()) {
                case 0:
                    licenseDTO.setExpireTime(DateUtil.offset(new Date(), DateField.DAY_OF_YEAR, licenseDTO.getCycleNum()));
                    break;
                case 1:
                    licenseDTO.setExpireTime(DateUtil.offset(new Date(), DateField.WEEK_OF_YEAR, licenseDTO.getCycleNum()));
                    break;
                case 2:
                    licenseDTO.setExpireTime(DateUtil.offset(new Date(), DateField.MONTH, licenseDTO.getCycleNum()));
                    break;
                case 3:
                    licenseDTO.setExpireTime(DateUtil.offset(new Date(), DateField.YEAR, licenseDTO.getCycleNum()));
                    break;
            }
        }
        Date currentDate = new Date();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("mac", licenseDTO.getMac());
        jsonObject.put("createtime", DateUtil.format(currentDate, "yyyy-MM-dd HH:mm:ss"));
        jsonObject.put("expiretime", DateUtil.format(licenseDTO.getExpireTime(), "yyyy-MM-dd HH:mm:ss"));
        String encryContent = encryptAES(jsonObject.toString());

        TpLicenseInfo info = new TpLicenseInfo();
        info.setCustomerName(licenseDTO.getCustomerName());
        info.setExpireTime(licenseDTO.getExpireTime());
        info.setIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
        info.setUserId(getUserId());
        info.setCreateTime(currentDate);
        info.setMac(licenseDTO.getMac());
        tpLicenseInfoService.insertTpLicenseInfo(info);
        return AjaxResult.success(encryContent);
    }


    /**
     * AES加密
     *
     * @param content 明文
     * @return 密文
     */
    public static String encryptAES(String content) {
        if (StringUtil.isEmpty(content)) {
            throw new RuntimeException("明文不能为空！");
        }
        byte[] encryptResult = encrypt(content, PASSWORD);
        String encryptResultStr = parseByte2HexStr(encryptResult);
        // BASE64位加密
        encryptResultStr = ebotongEncrypto(encryptResultStr);
        return encryptResultStr;
    }


    /**
     * 加密字符串
     */
    private static String ebotongEncrypto(String str) {
        String result = str;
        if (str != null && str.length() > 0) {
            try {
                byte[] encodeByte = str.getBytes(ENCODING);
                result = Base64Utils.encodeToString(encodeByte);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        // base64加密超过一定长度会自动换行 需要去除换行符
        return result.replaceAll("\r\n", "").replaceAll("\r", "").replaceAll("\n", "");
    }


    /**
     * 加密
     *
     * @param content  需要加密的内容
     * @param password 加密密码
     * @return
     */
    private static byte[] encrypt(String content, String password) {
        try {
            KeyGenerator kgen = KeyGenerator.getInstance("AES");
            // 注意这句是关键，防止linux下 随机生成key。用其他方式在Windows上正常，但Linux上会有问题
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            secureRandom.setSeed(password.getBytes());
            kgen.init(128, secureRandom);
            // kgen.init(128, new SecureRandom(password.getBytes()));
            SecretKey secretKey = kgen.generateKey();
            byte[] enCodeFormat = secretKey.getEncoded();
            SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
            Cipher cipher = Cipher.getInstance("AES");// 创建密码器
            byte[] byteContent = content.getBytes("utf-8");
            cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
            byte[] result = cipher.doFinal(byteContent);
            return result; // 加密
        } catch (Exception e) {
            System.out.println("加密异常");
        }
        return null;
    }

    /**
     * 将二进制转换成16进制
     *
     * @param buf
     * @return
     */
    private static String parseByte2HexStr(byte buf[]) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < buf.length; i++) {
            String hex = Integer.toHexString(buf[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            sb.append(hex.toUpperCase());
        }
        return sb.toString();
    }


    private static List<String> getLocalHostLANAddress() throws Exception {
        List<String> ips = new ArrayList<>();
        Enumeration<NetworkInterface> interfs = NetworkInterface.getNetworkInterfaces();
        while (interfs.hasMoreElements()) {
            NetworkInterface interf = interfs.nextElement();
            Enumeration<InetAddress> addres = interf.getInetAddresses();
            while (addres.hasMoreElements()) {
                InetAddress in = addres.nextElement();
                if (in instanceof Inet4Address) {
                    System.out.println("v4:" + in.getHostAddress());
                    if (!"127.0.0.1".equals(in.getHostAddress())) {
                        ips.add(in.getHostAddress());
                    }
                }
            }
        }
        return ips;
    }


}
